﻿using System;
using System.Collections.Generic;
using System.Text;
using Tsanie.DmPoster.Utils;
using Tsanie.DmPoster.Event;
using System.Web;

namespace Tsanie.DmPoster.Models {
    /// <summary>
    /// Bili弹幕属性枚举
    /// </summary>
    public enum BiliProperty {
        Message,
        Color,
        Fontsize,
        Mode,
        PlayTime
    }

    /// <summary>
    /// BiliBili弹幕
    /// </summary>
    public class BiliComment : CommentBase {

        /// <summary>Bili弹幕内容</summary>
        public override string Message {
            get { return base.Message; }
            set {
                if (string.IsNullOrEmpty(value))
                    throw new BiliException("弹幕内容不可为空！");
                base.Message = value;
                if (_propertyChanged != null)
                    _propertyChanged(this, BiliProperty.Message);
            }
        }

        /// <summary>Bili弹幕颜色</summary>
        public override int Color {
            get { return base.Color; }
            set {
                base.Color = value;
                if (_propertyChanged != null)
                    _propertyChanged(this, BiliProperty.Color);
            }
        }

        /// <summary>Bili弹幕字号大小</summary>
        public override int Fontsize {
            get { return base.Fontsize; }
            set {
                if (value <= 0)
                    throw new BiliException("弹幕字号大小不可为负！");
                base.Fontsize = value;
                if (_propertyChanged != null)
                    _propertyChanged(this, BiliProperty.Fontsize);
            }
        }

        private int mode;
        /// <summary>
        /// Bili弹幕模式
        /// <para>1 - 滚动弹幕</para>
        /// <para>4 - 底端固定弹幕</para>
        /// <para>5 - 顶端固定弹幕</para>
        /// <para>6 - 逆向滚动弹幕</para>
        /// <para>7 - 定位弹幕</para>
        /// </summary>
        public int Mode {
            get { return mode; }
            set {
                if (value != 1 && value < 4 && value > 7)
                    throw new BiliException("弹幕模式不对！");
                this.mode = value;
                if (value == 1 || value == 6)
                    SetLife(4f);
                else if (value != 7)
                    SetLife(3.5f);
                if (_propertyChanged != null)
                    _propertyChanged(this, BiliProperty.Mode);
            }
        }

        protected float life;
        /// <summary>BiliPos弹幕生存时间</summary>
        public virtual float Life {
            get { return this.life; }
            set {
                SetLife(value);
                if (_propertyChanged != null)
                    _propertyChanged(this, BiliProperty.Mode);
            }
        }
        protected void SetLife(float value) {
            if (value <= 0 || value > 10)
                throw new BiliException("“" + value + "”" + "弹幕生存时间不在（0,10] 之间！");
            this.life = value;
        }

        /// <summary>Bili弹幕播放时间</summary>
        public override float PlayTime {
            get { return base.PlayTime; }
            set {
                if (value < 0)
                    throw new BiliException("弹幕播放时间不可为负！");
                if (base.PlayTime != value) {
                    base.PlayTime = value;
                    if (_propertyChanged != null)
                        _propertyChanged(this, BiliProperty.PlayTime);
                }
            }
        }

        private int? width;
        /// <summary>获取或设置Bili弹幕宽度</summary>
        public int Width {
            get { return (this.width.HasValue ? this.width.Value : -1); }
            set { this.width = value; }
        }

        private int? height;
        /// <summary>获取或设置Bili弹幕高度</summary>
        public int Height {
            get { return (this.height.HasValue ? this.height.Value : -1); }
            set { this.height = value; }
        }

        internal int? X { get; set; }
        internal int? Y { get; set; }

        /// <summary>获取或设置弹幕绑定用户</summary>
        public string User { get; set; }

        public static string SubtitlesToString(IEnumerable<BiliComment> comments,
            float offset) {
            StringBuilder builder = new StringBuilder();
            int index = 0;
            foreach (BiliComment comm in comments) {
                builder.Append("&time[" + index + "]=" + (comm.PlayTime - offset)
                    + "&msg[" + index + "]=" + HttpUtility.UrlEncode(
                        comm.Message.Replace("\r", "").Replace("\n", "/n"), Encoding.UTF8)
                    + "&fs[" + index + "]=" + comm.Fontsize
                    + "&cl[" + index + "]=" + comm.Color.ToString("X6")
                    + "&mo[" + index + "]=" + comm.Mode);
                index++;
            }
            return builder.ToString();
        }

        public BiliComment Clone() {
            BiliComment comm = new BiliComment();
            comm.Message = this.Message;
            comm.Color = this.Color;
            comm.Fontsize = this.Fontsize;
            comm.Mode = this.Mode;
            comm.PlayTime = this.PlayTime;
            comm.User = this.User;
            comm._propertyChanged = this._propertyChanged;
            return comm;
        }
    }
}
